// 不同对象的数据, 使用proxy的getter/setter方法,在getter中设置track, 在setter中添加trigger
// 通过抽离effect方法
// 通过ref，定义相关联的响应式数据
// 实现computed方法

let targetMap = new WeakMap();
let activeEffect = null;
const effect = (eff) => {
  activeEffect = eff;
  activeEffect();
  activeEffect = null;
};
const track = (target, key) => {
  if (activeEffect) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
      depsMap = new Map();
      targetMap.set(target, depsMap);
    }
    let deps = depsMap.get(key);
    if (!deps) {
      deps = new Set();
      depsMap.set(key, deps);
    }
    deps.add(activeEffect);
  }
};

const trigger = (target, key) => {
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    return;
  }
  let deps = depsMap.get(key);
  if (deps) {
    deps.forEach((effect) => {
      effect();
    });
  }
};
const reactive = (target) => {
  const handler = {
    get(target, key, receiver) {
      console.log(`read get data: ${key}`);
      const result = Reflect.get(target, key, receiver);
      track(target, key);
      return result;
    },
    set(target, key, value, receiver) {
      console.log(`set data: ${key}`);
      const oldValue = target[key];
      const result = Reflect.set(target, key, value, receiver);
      if (value != oldValue) {
        trigger(target, key);
      }
      return result;
    }
  }
  return new Proxy(target, handler)
}
// vue3中实现ref的方法
const ref = raw => {
  const r = {
    get value() {
      track(r, 'value');
      return raw;
    },
    set value(newValue) {
      raw = newValue;
      trigger(r, 'value');
    }
  }
  return r;
}
// vue3 computed
const computed = raw => {
  let result = ref()
  effect(()=> result.value = raw());
  return result;
}

let product = reactive({
    price: 20,
    quantity: 3,
  }),
  car = reactive({
    price: 123455,
    quantity: 2
  });

let salePrice = computed(()=>{
  return product.price *0.9;
})
let total = computed(()=>{
  return salePrice.value * product.quantity;
})

console.log(total.value, salePrice.value);
product.quantity = 5;
console.log(total.value, salePrice.value);
product.price = 4565;
console.log(total.value, typeof salePrice.value);
